package org.javaboy.redis.service;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;

@Component
public class OrderNoUtil {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //初始值
    private static final String ORDER_INIT = "0";
    //订单缓存key
    private static final String ORDER_KEY = "ORDER_KEY";
    //订单ID前缀
    private static final String ORDER_ID_PREFIX = "Z";
    //时间格式化
    private static final String DATE_FORMAT = "yyyyMMddHHmmssSSS";
    private static final int MAXLEN = 8;

    /**
     * 生成唯一订单编号
     * @return
     */
    public String generateOrderNo(String orderNoPrefix){
        String id = generateUniqueId(ORDER_KEY);
        String orderId = format(id, orderNoPrefix);

        return orderId;
    }

    /**
     * 通过key获取自增并设定过期时间
     * @param key
     * @return
     */
    private String generateUniqueId(String key) {
        ValueOperations ops = stringRedisTemplate.opsForValue();
        String orderNo="";
        if(stringRedisTemplate.hasKey(key)){
            orderNo=ops.get(key).toString();
        }

        if(StringUtils.isEmpty(orderNo)){
            ops.set(key,ORDER_INIT,getExpireDuration());
        }
        orderNo=ops.increment(key).toString();
        int length = orderNo.length();
        StringBuffer sb = new StringBuffer();
        if(length<MAXLEN){
            for(int i=0;i<(MAXLEN-length);i++){
                sb.append("0");
            }
            sb.append(orderNo);
        }
        return sb.toString();
    }

    /**
     * 过期时间为第二天凌晨
     * @return
     */
    public Duration getExpireDuration(){
        LocalDateTime now=LocalDateTime.now();
        LocalDateTime expireDate=now.plusDays(1);
        LocalDateTime expireTime=LocalDateTime.of(expireDate.getYear(),expireDate.getMonthValue(),expireDate.getDayOfMonth(),0,0,0);

        return Duration.between(now,expireTime);
    }

    /**
     * 格式化时间
     * @param format 时间格式
     * @return
     */
    public  String getDateFormat(String format){
        DateFormat df = new SimpleDateFormat(null == format || "".equals(format) ? DATE_FORMAT : format);
        return df.format(new Date());
    }

    /**
     * 自定义ID格式
     * @param id
     * @param prefix 前缀
     * @return
     */
    private  String format(String id,String prefix){
        StringBuffer sb = new StringBuffer();
        if(null != prefix && !"".equals(prefix)){
            sb.append(prefix);
        }
        sb.append(getDateFormat(null));//当前时间戳
        String strId = sb.toString()+id;

        return strId;
    }

    public static void main(String[] args) {
//        Date expiredDate=getExpireAtData();
//
//        System.out.println(expiredDate);
    }

}
